package slb

import (
	"encoding/json"
	"fmt"
	"strings"

	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	slb20140515 "github.com/alibabacloud-go/slb-20140515/v4/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	credential "github.com/aliyun/credentials-go/credentials"
)

func CreateSlbClient(accessKey, accessSecret, area string) (_result *slb20140515.Client, _err error) {
	credential, _err := credential.NewCredential(nil)
	if _err != nil {
		return _result, _err
	}

	config := &openapi.Config{
		Credential:      credential,
		AccessKeyId:     &accessKey,
		AccessKeySecret: &accessSecret,
	}
	// See https://api.alibabacloud.com/product/Slb.
	endpoint := new(string)
	if area == "cn-hangzhou" {
		*endpoint = "slb.aliyuncs.com"
	} else {
		*endpoint = fmt.Sprintf("slb.%s.aliyuncs.com", area)
	}
	config.Endpoint = endpoint
	_result = &slb20140515.Client{}
	_result, _err = slb20140515.NewClient(config)
	return _result, _err
}

func SetLBCert(client *slb20140515.Client, certResp *slb20140515.UploadServerCertificateResponse, instanceid *string, port *int) error {
	setLoadBalancerHTTPSListenerAttributeRequest := &slb20140515.SetLoadBalancerHTTPSListenerAttributeRequest{
		RegionId:            certResp.Body.RegionId,
		LoadBalancerId:      instanceid,
		ListenerPort:        tea.Int32(int32(*port)),
		ServerCertificateId: certResp.Body.ServerCertificateId,
	}
	runtime := &util.RuntimeOptions{}

	_, _err := client.SetLoadBalancerHTTPSListenerAttributeWithOptions(setLoadBalancerHTTPSListenerAttributeRequest, runtime)
	if _err != nil {
		return _err
	}
	return nil
}

func errorParse(e error) (_err error) {
	var error = &tea.SDKError{}
	if _t, ok := e.(*tea.SDKError); ok {
		error = _t
	} else {
		error.Message = tea.String(e.Error())
	}
	fmt.Println(tea.StringValue(error.Message))
	var data interface{}
	d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
	d.Decode(&data)
	if m, ok := data.(map[string]interface{}); ok {
		recommend := m["Recommend"]
		fmt.Println(recommend)
	}
	_, _err = util.AssertAsString(error.Message)
	if _err != nil {
		return _err
	}
	return
}

func UploadCertToSlb(client *slb20140515.Client, area, certPEM, privkeyPEM string) (_resp *slb20140515.UploadServerCertificateResponse, _err error) {
	uploadServerCertificateRequest := &slb20140515.UploadServerCertificateRequest{
		RegionId:          tea.String(area),
		ServerCertificate: tea.String(strings.ReplaceAll(certPEM, "\n\n", "\n")),
		PrivateKey:        tea.String(strings.ReplaceAll(privkeyPEM, "\n\n", "\n")),
	}
	runtime := &util.RuntimeOptions{}

	_resp, _err = client.UploadServerCertificateWithOptions(uploadServerCertificateRequest, runtime)
	if _err != nil {
		errorParse(_err)
		return
	}
	if *_resp.StatusCode != 200 {
		return
	}
	return
}

func ListCertFromSlb(client *slb20140515.Client, area string) (_resp *slb20140515.DescribeServerCertificatesResponse, _err error) {
	describeServerCertificatesRequest := &slb20140515.DescribeServerCertificatesRequest{
		RegionId: tea.String(area),
	}
	runtime := &util.RuntimeOptions{}

	_resp, _err = client.DescribeServerCertificatesWithOptions(describeServerCertificatesRequest, runtime)
	if _err != nil {
		return
	}
	return
}

func DeleteSlbCert(client *slb20140515.Client, area, certID string) error {
	deleteServerCertificateRequest := &slb20140515.DeleteServerCertificateRequest{
		RegionId:            tea.String(area),
		ServerCertificateId: tea.String(certID),
	}
	runtime := &util.RuntimeOptions{}

	_, _err := client.DeleteServerCertificateWithOptions(deleteServerCertificateRequest, runtime)
	if _err != nil {
		return _err
	}
	return nil
}
